﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Log4Net;

namespace PollServer
{
    //定义委托
    public delegate bool GameDbDelegate(object _db);

    public class LockFreeThread
    {
        //委托事件处理
        public GameDbDelegate _dealelegate;
        //加入超时处理
        public ManualResetEvent mTimeoutObject;
        //变量标识
        public bool mBoTimeout;

        public LockFreeThread(GameDbDelegate dealelegate)
        {
            _dealelegate = dealelegate;
            mBoTimeout = true;
            mTimeoutObject = new ManualResetEvent(true);  //设置为停止状态
        }

        public static void run(object obj)
        {
            LockFreeThread lfThread = obj as LockFreeThread;
            lfThread.RunWork();
        }

        ///<summary>
        /// 指定超时时间 异步执行某个方法
        ///</summary>
        ///<returns>执行 是否超时</returns>
        public bool DoWithTimeout(TimeSpan timeSpan, object node )
        {
            if (this._dealelegate == null)
            {
                return false;
            }
            this.mTimeoutObject.Reset();
            this.mBoTimeout = true; //标记
            this._dealelegate.BeginInvoke(node, DoAsyncCallBack, null);
            // 等待 信号Set
            if (!this.mTimeoutObject.WaitOne(timeSpan, false))
            {
                this.mBoTimeout = true;
            }
            return this.mBoTimeout;
        }

        ///<summary>
        /// 异步委托 回调函数
        ///</summary>
        ///<param name="result"></param>
        private void DoAsyncCallBack(IAsyncResult result)
        {
            try
            {
                this._dealelegate.EndInvoke(result);
                // 指示方法的执行未超时
                this.mBoTimeout = false;
            }
            catch (MySql.Data.MySqlClient.MySqlException ex)
            {
                LogHelper.WriteLog("MySqlException 异常：", ex);
                this.mBoTimeout = true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("LockFreeThread 异常：", ex);
                this.mBoTimeout = true;
            }
            finally
            {
                this.mTimeoutObject.Set();
            }
        }

        //处理线程 从队列中获取处理节点并处理
        public void RunWork()
        {
            LockFreeQueue queue = LockFreeQueue.Queue;
            while (true)
            {
                object node = queue.pop();
                 if (node != null)
                {
                     //10秒执行超时
                    bool bo = DoWithTimeout(new TimeSpan(0, 0, 0, 30), node);
                     //执行
                     //_dealelegate(node);
                    //Console.WriteLine(string.Format("4秒超时执行结果,是否超时：{0}", bo));
                    if (bo)
                    {
                        Form1.timeout_console_node(node);
                    }
                    Thread.Sleep(100);
                }
                else
                {//若没有取到数据 则加大线程睡眠时间
                    Thread.Sleep(1000);
                }
                /*
                catch (MySql.Data.MySqlClient.MySqlException ex)
                {
                    LogHelper.WriteLog("MySqlException 异常：", ex);
                    Thread.Sleep(500);
                }
                catch (System.Exception ex)
                {
                    //保证处理函数出现异常时，不会退出线程
                    LogHelper.WriteLog("LockFreeThread 异常：", ex);
                    Thread.Sleep(1000);
                }
                 * */
            }
        }
    }
}
